﻿using System.ComponentModel;
using System.Runtime.Serialization;
using System.Xml;
using System.Xml.Serialization;
using NewLife;
using NewLife.Collections;

namespace XCode.DataAccessLayer;

/// <summary>字段构架</summary>
[Serializable]
[DisplayName("字段模型")]
[Description("字段模型")]
[XmlRoot("Column")]
class XField : SerializableDataMember, IDataColumn, ICloneable
{
    #region 属性
    /// <summary>名称</summary>
    [XmlAttribute]
    [DisplayName("名称")]
    [Description("名称")]
    public String Name { get; set; } = null!;

    /// <summary>列名</summary>
    [XmlAttribute]
    [DisplayName("列名")]
    [Description("列名")]
    public String ColumnName { get; set; } = null!;

    /// <summary>数据类型</summary>
    [XmlAttribute]
    [DisplayName("数据类型")]
    [Description("数据类型")]
    public Type DataType { get; set; }

    /// <summary>原始数据类型</summary>
    [XmlAttribute]
    [DisplayName("原始类型")]
    [Description("原始类型")]
    public String? RawType { get; set; }

    /// <summary>元素类型</summary>
    [XmlAttribute]
    [DisplayName("元素类型")]
    [Description("元素类型")]
    public String? ItemType { get; set; }

    /// <summary>映射，表间关联，格式Role.Id.Name</summary>
    [XmlAttribute]
    [DisplayName("映射")]
    [Description("映射，表间关联")]
    public String? Map { get; set; }

    /// <summary>标识</summary>
    [XmlAttribute]
    [DisplayName("标识")]
    [Description("标识")]
    public Boolean Identity { get; set; }

    /// <summary>主键</summary>
    [XmlAttribute]
    [DisplayName("主键")]
    [Description("主键")]
    public Boolean PrimaryKey { get; set; }

    /// <summary>是否主字段。主字段作为业务主要字段，代表当前数据行意义</summary>
    [XmlAttribute]
    [DisplayName("主字段")]
    [Description("主字段")]
    public Boolean Master { get; set; }

    /// <summary>长度</summary>
    [XmlAttribute]
    [DisplayName("长度")]
    [Description("长度")]
    public Int32 Length { get; set; }

    /// <summary>精度</summary>
    [XmlAttribute]
    [DisplayName("精度")]
    [Description("精度")]
    public Int32 Precision { get; set; }

    /// <summary>位数</summary>
    [XmlAttribute]
    [DisplayName("位数")]
    [Description("位数")]
    public Int32 Scale { get; set; }

    /// <summary>允许空</summary>
    [XmlAttribute]
    [DisplayName("允许空")]
    [Description("允许空")]
    public Boolean Nullable { get; set; }

    /// <summary>数据规模。time表示这是大数据单表的数据时间字段，timeShard:yyMMdd表示这是大数据多表的分表字段</summary>
    [XmlAttribute]
    [DisplayName("数据规模")]
    [Description("数据规模。time表示这是大数据单表的数据时间字段，timeShard:yyMMdd表示这是大数据多表的分表字段")]
    public String? DataScale { get; set; }

    /// <summary>默认值</summary>
    [XmlAttribute]
    [DisplayName("默认值")]
    [Description("默认值")]
    public String? DefaultValue { get; set; }

    ///// <summary>元素参数默认值</summary>
    //[XmlAttribute]
    //[DisplayName("元素参数默认值")]
    //[Description("元素参数默认值")]
    //public String? ItemDefaultValue { get; set; }

    private String? _Description;
    /// <summary>描述</summary>
    [XmlAttribute]
    [DisplayName("描述")]
    [Description("描述")]
    public String? Description
    {
        get { return _Description; }
        set
        {
            if (!value.IsNullOrEmpty()) value = value.Replace("\r\n", "。").Replace("\r", " ").Replace("\n", " ");
            _Description = value;
        }
    }
    #endregion

    #region 扩展属性
    /// <summary>表</summary>
    [XmlIgnore, IgnoreDataMember]
    public IDataTable Table { get; set; } = null!;

    private String? _DisplayName;
    /// <summary>显示名</summary>
    [XmlAttribute]
    [DisplayName("显示名")]
    [Description("显示名")]
    public String? DisplayName
    {
        get
        {
            if (String.IsNullOrEmpty(_DisplayName)) _DisplayName = ModelResolver.Current.GetDisplayName(Name, _Description);
            return _DisplayName;
        }
    }

    /// <summary>扩展属性</summary>
    [XmlIgnore, IgnoreDataMember]
    [Category("扩展")]
    [DisplayName("扩展属性")]
    [Description("扩展属性")]
    public IDictionary<String, String> Properties { get; } = new NullableDictionary<String, String>(StringComparer.OrdinalIgnoreCase);
    #endregion

    #region 构造
    ///// <summary>实例化</summary>
    //public XField() { }
    #endregion

    #region 方法
    /// <summary>重新计算修正别名。避免与其它字段名或表名相同，避免关键字</summary>
    /// <returns></returns>
    public IDataColumn Fix()
    {
        return ModelResolver.Current.Fix(this);
    }

    /// <summary>已重载。</summary>
    /// <returns></returns>
    public override String ToString()
    {
        if (!String.IsNullOrEmpty(DisplayName) && DisplayName != Name)
            return $"Name={ColumnName} DataType={DataType?.Name} RawType={RawType} DisplayName={DisplayName}";
        else
            return $"Name={ColumnName} DataType={DataType?.Name} RawType={RawType}";
    }
    #endregion

    #region ICloneable 成员
    /// <summary>克隆</summary>
    /// <returns></returns>
    Object ICloneable.Clone() => Clone(Table);

    /// <summary>克隆</summary>
    /// <param name="table"></param>
    /// <returns></returns>
    public IDataColumn Clone(IDataTable table)
    {
        var field = base.MemberwiseClone() as XField;
        field.Table = table;
        //field.Fix();

        return field;
    }
    #endregion
}